/**
 * SPDX-FileCopyrightText: 2023-2025 Sangfor Technologies Inc.
 * SPDX-License-Identifier: Mulan PSL v2
 */
<template>
    <sf-grid class="webserice-table">
        <sf-table
            ref="streamServiceTable"
            :options="options_fix"
            @pagechange="_onPageChange"
            @sizechange="_onSizeChange">
            <sf-table-column :default-width="40"
                             type="index">
                <lang>序号</lang>
            </sf-table-column>
            <sf-table-column data-index="name"
                             :default-width="100">
                <lang>服务名称</lang>
            </sf-table-column>
            <sf-table-column data-index="remoteJobState"
                             :default-width="100">
                <lang>服务状态</lang>
            </sf-table-column>
            <sf-table-column data-index="modelName"
                             :default-width="80">
                <lang>对应模型</lang>
            </sf-table-column>
            <sf-table-column data-index="numExecutors"
                             :default-width="60">
                <lang>实例数</lang>
            </sf-table-column>
            <sf-table-column data-index="run_time"
                             :default-width="100">
                <lang>运行环境</lang>
            </sf-table-column>
            <sf-table-column data-index="description"
                             :default-width="120">
                <lang>描述</lang>
            </sf-table-column>

            <sf-table-column data-index="opr"
                             :default-width="120">
                <lang>操作</lang>
                <sf-fieldtip>
                    <lang>若需编辑服务配置内容，请先下线服务。</lang>
                </sf-fieldtip>
            </sf-table-column>
            <!--额外操作-->

            <template slot="modelName"
                      slot-scope="{ record }">
                <span>{{ record.modelName }}</span>
            </template>
            <template slot="maxReplicas"
                      slot-scope="{ record }">
                <span>{{ record.numExecutors }}</span>
            </template>
            <template slot="remoteJobState"
                      slot-scope="{ record }">
                <span
                    class="common-status"
                    :class="serviceStatusClass(record.remoteJobState)"></span>
                <sf-fieldtip v-if="record.remoteJobState==='2'"
                             class="failed-tips">
                    <lang>失败原因可能是：资源不够、模型或镜像错误，请检查后再次尝试。</lang>
                </sf-fieldtip>
            </template>
            <template slot="run_time"
                      slot-scope="{ record }">
                <div class="run-time__list">
                    <div class="run-time">
                        <span class="name">CPU:</span>
                        <span class="value">{{ record.executorCores }}核</span>
                    </div>
                    <div class="run-time">
                        <span class="name">内存:</span>
                        <span class="value">{{ record.executorMemory }}</span>
                    </div>
                </div>
            </template>
            <template slot="opr"
                      slot-scope="{ record }">
                <div class="table-opr">
                    <a
                        v-if="record.remoteJobState !== '1'"
                        class="link-btn"
                        @click="_offlineService(record)">
                        <lang>下线</lang>
                    </a>
                    <!-- 除了成功是已下线，其它3种情况都是显示上线 -->
                    <a
                        v-if="record.remoteJobState === '1'"
                        class="link-btn"
                        @click="_onlineService(record)">
                        <lang>上线</lang>
                    </a>

                    <a
                        v-if="
                            record.remoteJobState === '0' ||
                                record.remoteJobState === '3'
                        "
                        class="link-btn"
                        @click="_readService(record)">
                        <lang>详情</lang>
                    </a>

                    <a
                        v-if="
                            record.remoteJobState === '1' ||
                                record.remoteJobState === '2'
                        "
                        class="link-btn"
                        @click="_editStreamServiceManager(record)">
                        <lang>编辑</lang>
                    </a>

                    <a class="link-btn"
                       @click="_deleteService(record)">
                        <lang>删除</lang>
                    </a>
                </div>
            </template>
        </sf-table>
    </sf-grid>
</template>
<script>
import urlAdapter from 'src/home/mod_common/url_adapter';
const SERVICE_GET = urlAdapter('streaming');
const SERVICE_PETCH = urlAdapter('streaming/job');
const SERVICE_DELETE = urlAdapter('streaming/job');

import IntervalTask from 'src/util/interval_task';
const STREANUING_JOB = urlAdapter('streaming/job');

import {
    STREAM_SERVICE_STATUS_NAME
} from '../const';

const PAGE_COUNT = 10;

import streamServiceForm from 'src/home/mod_cluster/project_manager/components/label_form/stream_service_form.vue';
import readStreamServiceForm from 'src/home/mod_cluster/project_manager/components/label_form/read_stream_service.vue';

export default {
    name: 'StreamRelease',
    props: {
        modelList: {
            type: Array,
            default: () => []
        }
    },
    data () {
        return {
            emptyText: _('暂无服务管理，请在“模型仓库”页部署服务'),
            options_fix: {
                bufferView: false,

                // 配置这个后才可以实现保持勾选状态
                idProperty: 'id',
                selectionHide: true,
                forceFit: false,
                pagination: {
                    activePage: 1,
                    pageSize: PAGE_COUNT,
                    pageSizes: [Number('10'), Number('20'), Number('50')],
                    layout: ['pager', 'jumper']
                }
            },
            searchParams: {
                pageSize: PAGE_COUNT,
                pageNum: 0,
                keyword: ''
            },
            intervalTask: null

        };
    },
    computed: {
        projectId () {
            return this.$route.query.projectId || '';
        }
    },
    mounted () {
        this._createIntervalTask();
    },
    methods: {
        _createIntervalTask () {
            let vm = this;
            this.intervalTask = new IntervalTask({
                fn: () => {
                    vm.refreshGrid().then(() => {
                        vm.intervalTask && vm.intervalTask.next();
                    });
                },
                interval: 5000,
                autoStart: true
            });
        },
        serviceStatusClass (status) {
            let statusClass = status ? STREAM_SERVICE_STATUS_NAME[status] : 'starting';
            return statusClass;
        },



        onEnterkey () {
            this.refreshGrid();
        },

        // 刷新grid
        async refreshGrid (params) {
            if (params) {
                this.searchParams.keyword = params.keyword;
            }
            this.searchParams.projectId = this.projectId;
            let jsonData = await this.$ajax.get(`${SERVICE_GET}/${this.projectId}/job`, this.searchParams);
            let table = this.$refs.streamServiceTable;
            let { success, msg, data } = jsonData;
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            };
            let { list } = data;

            if (!this.searchParams.keyword) {
                this.$emit('get-total', data.total);
            }
            table && table.loadData(list || []);
            table && table.getPagination().setTotal(data.total);
            let startingLength = list ? list.filter(item => item.remoteJobState === '3').length : false;

            // 存在启动中这种情况才会定时刷新,不存在loading则可以关掉定时器。
            if (!startingLength) {
                this.intervalTask && this.intervalTask.stop();
            }


            this.$nextTick().then(() => {
                table && table.resetColumnsWidth();
            });
        },

        // 下线
        _offlineService (record) {
            this.$confirm({
                title: _('确定'),
                subTitle: `确定要下线${record.name}服务吗？`,
                msg: `服务下线后将即时生效，可能对业务状态带来一定影响，请再次确认。`,
                icon: 'warning',
                autoClose: true,
                callback: actionName => {
                    if (actionName === 'submit') {
                        this._ajaxOfflineOprService(record);
                    }
                }
            });
        },
        async _ajaxOfflineOprService (record) {
            const PATCH_URL = `${SERVICE_PETCH}/${record.id}/status/offline`;
            this.$mask();
            let jsonData = await this.$ajax.post(PATCH_URL, {});
            let { success, msg } = jsonData;
            this.$unmask();
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            }
            this.refreshGrid();
        },

        // 上线
        _onlineService (record) {
            this.$confirm({
                title: _('确定'),
                subTitle: `确定要上线${record.name}服务吗？`,
                msg: `服务上线后将即时生效，可能对业务状态带来一定影响，请再次确认。`,
                icon: 'warning',
                autoClose: true,
                callback: actionName => {
                    if (actionName === 'submit') {
                        this._ajaxOnlineOprService(record);
                    }
                }
            });
        },
        async _ajaxOnlineOprService (record) {
            this.$confirm({
                title: _('上线'),
                subTitle: _('是否接入实时数据？'),
                msg: _('建议接入实时数据，上线快稳定，但会丢失之前的历史数据；<br/>如果接入历史数据，当历史数据过大时，上线需等待30分钟或<br/>几个小时，且很有可能失败，建议增加计算资源后重试。'),
                autoDestroy: true,
                autoClose: true,
                buttons: [{
                    cls: 'visual-save-exit-btn',
                    actionName: 'save',
                    text: _('接入历史数据')
                }, {
                    actionName: 'submit',
                    text: _('接入实时数据')
                }, {
                    actionName: 'cancel',
                    text: '取消'
                }],
                save: () => {
                    this._fetchOnline(record, { realTimeState: false });
                },
                submit: () => {
                    this._fetchOnline(record, { realTimeState: true });
                }
            });
        },
        async _fetchOnline (record, params) {
            const PATCH_URL = `${SERVICE_PETCH}/${record.id}/status/online`;
            this.$mask();
            let jsonData = await this.$ajax.post(PATCH_URL, params);
            let { success, msg } = jsonData;
            this.$unmask();
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            }

            this.refreshGrid();
        },
        async ajaxDeleteService (record) {
            const DELETE_URL = `${SERVICE_DELETE}/${record.id}`;
            this.$mask();
            let jsonData = await this.$ajax.delete(DELETE_URL, {});
            this.$unmask();
            let { success, msg } = jsonData;
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            }
            this.$ok(_('删除服务成功'));
            this.refreshGrid();
        },
        _deleteService (record) {
            this.$confirm({
                title: _('提示'),
                subTitle: _('确定要删除{0}服务吗？', record.name),
                msg: '',
                icon: 'warning',
                autoClose: true,
                callback: actionName => {
                    if (actionName === 'submit') {
                        this.ajaxDeleteService(record);
                    }
                }
            });
        },
        _copySuccess () {
            this.$ok(_('复制成功'));
        },

        // 部署stream服务弹窗
        _createReadStreamServiceFormWin () {
            if (!this.readStreamServiceFormWin) {
                this.readStreamServiceFormWin = this.$modal(readStreamServiceForm, {
                    autoDestory: true
                });
            }
            return this.readStreamServiceFormWin;
        },
        _readService (record) {
            let formWin = this._createReadStreamServiceFormWin();
            formWin.formRoot.setJsonValue(record);
            let showHighSet = !!record.advancedParameters;
            formWin.open({
                title: _('查看Stream Service服务详情'),
                data: {
                    showHighSet
                },
                buttons: [{
                    cls: 'btn-default',
                    text: '关闭',
                    actionName: 'cancel'
                }],
                cancel: () => {
                    formWin.hide();
                }
            });
        },


        // 部署stream服务弹窗
        _createStreamServiceFormWin () {
            if (!this.streamServiceFormWin) {
                this.streamServiceFormWin = this.$modal(streamServiceForm, {
                    autoDestory: true
                });
            }
            return this.streamServiceFormWin;
        },

        // 新增stream部署服务
        _editStreamServiceManager (record) {
            let formWin = this._createStreamServiceFormWin();
            formWin.formRoot.setJsonValue(record);
            let memorySize = Number(record.executorMemory.substr(0, record.executorMemory.length - 1));
            formWin.open({
                title: _('编辑Stream Service服务'),
                data: {
                    modelList: this.modelList,
                    showModelList: true,
                    resourceData: {
                        memorySize,
                        cpuNum: record.executorCores
                    }
                },
                callback: (actionName) => {
                    if (actionName === 'submit') {
                        if (!formWin.$refs.form.isValid()) {
                            this.$showErr(formWin.$refs.form.getInvalidMsgs());
                            return false;
                        }
                        let ajaxParams = formWin.formRoot.getJsonValue();
                        ajaxParams.projectId = this.projectId;
                        this.ajaxSubmitStreamService(ajaxParams, formWin);
                    }
                }
            });
        },

        // 新增/编辑算法的卡片信息
        async ajaxSubmitStreamService (params, formWin) {
            formWin.$mask();
            let url =  `${STREANUING_JOB}/${params.id}`;
            let jsonData = await this.$ajax.put(url, params);
            formWin.$unmask();
            let { success, msg } = jsonData;
            if (!success) {
                return this.$showErr(msg || _('编辑服务失败'));
            }
            this.$ok(_('编辑服务成功'));
            formWin.hide();
            this.refreshGrid();
        },
        _onPageChange (pageNum) {
            Object.assign(this.searchParams, {
                pageNum: pageNum - 1
            });
            this.refreshGrid();
        },
        _onSizeChange (nowPageIndex, nowPageSize) {
            Object.assign(this.searchParams, {
                pageNum: nowPageIndex - 1,
                pageSize: nowPageSize
            });
            this.refreshGrid();
        },
        _refresh () {
            this.refreshGrid();
        }

    },
    beforeDestroy () {
        this.intervalTask && this.intervalTask.stop();
        this.intervalTask = null;
    }
};
</script>
<style lang="less">
.webserice-table {
    border: none;
    height: 100%;
    display: flex;
    flex-direction: column;

    .sfv-table {
        flex: 1;
    }
    .formal-url {
        .iconfuzhi {
            display: none;
            cursor: pointer;
            &:hover {
                color: #204ed9;
            }
        }
        &:hover {
            .iconfuzhi {
                display: inline-block;
            }
        }
    }
    .common-url {
        width: 95%;
        display: inline-block;
        vertical-align: bottom;
        margin-right: 2px;
    }
    .failed-tips{
        font-size: 16px;
        margin-top: -10px;
        margin-left: -2px;
    }
    .common-status {
        width: 64px;
        display: inline-block;
        height: 18px;
        &.stopped {
            background: url(../../../../img/service/stopped.svg);
            background-size: 100% 100%;
        }
        &.ready {
            background: url(../../../../img/service/ready.svg);
            background-size: 100% 100%;
        }
        &.starting {
            background: url(../../../../img/service/starting.svg);
            background-size: 100% 100%;
        }
        &.failed {
            background: url(../../../../img/service/failed.svg);
            background-size: 100% 100%;
        }
    }
}
</style>
